package com.zb.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zb.entity.*;
import com.zb.excel.UserExcelExport;
import com.zb.extend.FactoryUserExtend;
import com.zb.extend.WorkGoodsExtend;
import com.zb.mapper.ZjUserContactMapper;
import com.zb.mapper.ZjUserMapper;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.user.service.ConUserService;
import com.zb.view.ViewGoods;
import com.zb.vo.UserListVo;
import com.zb.vo.UserRelationCodeGoodsListVo;
import com.zb.vo.UserRelationOrderListVo;
import com.zb.vo.UserSelectVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 *
 * @Author WEN
 * @Date 2023/9/19 0019
 **/
@Service
public class ConUserServiceImpl implements ConUserService {
    @Resource
    private ZjUserTypeService userTypeService;
    @Resource
    private ZjUserService userService;
    @Resource
    private ZjUserContactService userContactService;
    @Resource
    private ZjWorkUserService workUserService;
    @Resource
    private ZjCodeUserRegisterService codeUserRegisterService;
    @Resource
    private ZjWorkOrderService workOrderService;
    @Resource
    private ZjCodeService codeService;
    @Resource
    private ZjCodeInfoService codeInfoService;
    @Resource
    private ViewGoodsService viewGoodsService;
    @Resource
    private ZjWorkGoodsService workGoodsService;
    @Resource
    private ZjFactoryUserService factoryUserService;

    @Resource
    private ZjUserContactMapper userContactMapper;

    // 批量删除用户分类
    @Override
    public void deleteTypeBatchById(List<Long> idList) {
        userTypeService.removeByIds(idList);
    }

    // 获取用户列表
    @Override
    public Map<String, Object> getList(Long custAccId, UserSelectVo selectVo) {
        PageUtil.setPageLimit(selectVo);
        List<UserListVo> voList = userService.getList(custAccId, selectVo);
        List<Long> userIds = voList.stream().map(UserListVo::getId).toList();
        List<ZjWorkUser> workUserList = workUserService.getByUserIds(userIds);
        List<ZjCodeUserRegister> userRegisterList = codeUserRegisterService.getByUserIds(userIds);
        List<FactoryUserExtend> factoryUserExtends = factoryUserService.getByUserIds(userIds);
        voList.forEach(t -> {
            t.setOrderNo((int) workUserList.stream().filter(f -> Objects.equals(f.getUserId(), t.getId())).count());
            t.setProductNo((int) userRegisterList.stream().filter(f -> Objects.equals(f.getUserId(), t.getId())).count());
            t.setFactoryList(factoryUserExtends.stream().filter(f -> Objects.equals(f.getUserId(), t.getId())).map(FactoryUserExtend::getFactory).toList());
        });
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), userService.getListCount(custAccId, selectVo), voList);
    }

    // 获取客户关联的工单数量
    @Override
    public long getUserRelationOrderQty(Long userId) {
        QueryWrapper<ZjWorkUser> workUserQueryWrapper = new QueryWrapper<>();
        workUserQueryWrapper.select("id");
        workUserQueryWrapper.eq("user_id", userId);
        return workUserService.count(workUserQueryWrapper);
    }

    // 获取客户关联的工单列表
    @Override
    public Map<String, Object> getUserOrderList(Long userId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        QueryWrapper<ZjWorkUser> workUserQueryWrapper = new QueryWrapper<>();
        workUserQueryWrapper.select("id");
        workUserQueryWrapper.eq("user_id", userId);
        Page<ZjWorkUser> page = workUserService.page(new Page<>(pageUtil.getPage(), pageUtil.getLimit()), workUserQueryWrapper);
        if (CollectionUtil.isEmpty(page.getRecords())) {
            return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), new ArrayList<>());
        }
        QueryWrapper<ZjWorkOrder> workOrderQueryWrapper = new QueryWrapper<>();
        workOrderQueryWrapper.select("id", "code", "status", "end_time", "gmt_create");
        workOrderQueryWrapper.in("id", page.getRecords().stream().map(ZjWorkUser::getId).toList());
        List<ZjWorkOrder> orderList = workOrderService.list(workOrderQueryWrapper);

        List<WorkGoodsExtend> goodsExtendList = workGoodsService.getByWorkIds(orderList.stream().map(ZjWorkOrder::getId).toList());

        List<UserRelationOrderListVo> voList = orderList.stream().map(o -> {
            UserRelationOrderListVo vo = new UserRelationOrderListVo();
            vo.setId(o.getId());
            vo.setWorkNo(o.getCode());
            vo.setStatus(o.getStatus());
            vo.setEndTime(o.getEndTime());
            vo.setCreateTime(o.getGmtCreate());
            WorkGoodsExtend goodsExtend = goodsExtendList.stream().filter(f -> Objects.equals(f.getWorkId(), o.getId())).findFirst().orElse(null);
            if (null != goodsExtend) {
                vo.setGoodsBrand(goodsExtend.getGoodsBrand());
                vo.setGoodsType(goodsExtend.getGoodsType());
                vo.setGoodsName(goodsExtend.getGoodsName());
                vo.setGoodsModel(goodsExtend.getGoodsModel());
                vo.setGoodsSpecName(goodsExtend.getGoodsSpecName());
                vo.setImage(goodsExtend.getGoodsImage());
            }
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    // 获取客户关联的所有工单列表并判断是否有重复工单
    @Override
    public Map<String, Object> getUserOrderListWithoutPagination(Long userId) {
        QueryWrapper<ZjWorkUser> workUserQueryWrapper = new QueryWrapper<>();
        workUserQueryWrapper.select("id");
        workUserQueryWrapper.eq("user_id", userId);
        List<ZjWorkUser> workUserList = workUserService.list(workUserQueryWrapper);

        Map<String, Object> result = new HashMap<>();
        result.put("isValidOrder", false);
        result.put("orderDetails", new ArrayList<>());

        if (CollectionUtil.isEmpty(workUserList)) {
            return result;
        }

        QueryWrapper<ZjWorkOrder> workOrderQueryWrapper = new QueryWrapper<>();
        workOrderQueryWrapper.in("id", workUserList.stream().map(ZjWorkUser::getId).toList());
        List<ZjWorkOrder> orderList = workOrderService.list(workOrderQueryWrapper);

        if (!orderList.isEmpty()) {
            List<Map<String, Object>> validOrders = orderList.stream()
                    .filter(o -> o.getStatus() == 1 || o.getStatus() == 2 || o.getStatus() == 3)
                    .map(order -> {
                        Map<String, Object> orderDetail = new HashMap<>();
                        orderDetail.put("orderId", order.getId());
                        orderDetail.put("status", order.getStatus());
                        // 你可以根据需要添加更多的字段
                        return orderDetail;
                    })
                    .collect(Collectors.toList());
            result.put("isValidOrder", !validOrders.isEmpty());
            result.put("orderDetails", validOrders);
        }

        return result;
    }


    // 获取客户关联的编码商品数量
    @Override
    public long getUserRelationCodeGoodsQty(Long userId) {
        QueryWrapper<ZjCodeUserRegister> codeUserRegisterQueryWrapper = new QueryWrapper<>();
        codeUserRegisterQueryWrapper.select("id");
        codeUserRegisterQueryWrapper.eq("user_id", userId);
        return codeUserRegisterService.count(codeUserRegisterQueryWrapper);
    }

    // 获取客户关联的编码商品列表
    @Override
    public Map<String, Object> getUserRelationCodeGoodsList(Long userId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        QueryWrapper<ZjCodeUserRegister> codeUserRegisterQueryWrapper = new QueryWrapper<>();
        codeUserRegisterQueryWrapper.select("id");
        codeUserRegisterQueryWrapper.eq("user_id", userId);
        Page<ZjCodeUserRegister> page = codeUserRegisterService.page(new Page<>(pageUtil.getPage(), pageUtil.getLimit()), codeUserRegisterQueryWrapper);
        if (CollectionUtil.isEmpty(page.getRecords())) {
            return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), new ArrayList<>());
        }
        List<Long> codeIds = page.getRecords().stream().map(ZjCodeUserRegister::getId).toList();
        List<ZjCode> codeList = codeService.getRegisterByIds(codeIds);
        List<ZjCodeInfo> codeInfoList = codeInfoService.getRegistTimeByIds(codeIds);

        List<Long> productIds = codeList.stream().map(ZjCode::getGoodsId).distinct().toList();
        List<Long> productSpecIds = codeList.stream().map(ZjCode::getGoodsSpecId).distinct().toList();
        List<ViewGoods> viewGoodsList = viewGoodsService.getByGoodsIdsAndGoodsSpecIds(productIds, productSpecIds);

        List<UserRelationCodeGoodsListVo> voList = codeList.stream().map(co -> {
            UserRelationCodeGoodsListVo vo = new UserRelationCodeGoodsListVo();
            vo.setId(co.getId());
            vo.setCode(co.getSecurityCode());
            vo.setStatus(co.getStatus());
            vo.setRegisterTime(codeInfoList.stream().filter(f -> Objects.equals(f.getId(), co.getId())).map(ZjCodeInfo::getRegisterTime).findFirst().orElse(null));
            viewGoodsList.stream().filter(f -> Objects.equals(f.getId(), co.getGoodsId()) && Objects.equals(f.getSpecId(), co.getGoodsSpecId())).findFirst().ifPresent(specView -> {
                vo.setGoodsBrand(specView.getBrand());
                vo.setGoodsType(specView.getType());
                vo.setGoodsName(specView.getName());
                vo.setGoodsModel(specView.getModel());
                vo.setGoodsSpecName(specView.getSpecName());
                vo.setImage(specView.getImage());
            });
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    // 根据工单ID获取客户关联信息
    @Override
    public Map<String, Object> getUserRelationInfo(Long workId) {
        ZjWorkUser workUser = workUserService.getById(workId);
        Assert.isTrue(null != workUser, "工单ID参数[ " + workId + " ]的工单数据不存在");
        ZjUser user = userService.getById(workUser.getUserId());

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userId", workUser.getUserId());
        resultMap.put("userName", workUser.getName());
        resultMap.put("userPhone", workUser.getPhone());
        resultMap.put("userCode", user.getCode());
        resultMap.put("userCreateTime", user.getGmtCreate());
        resultMap.put("orderQty", getUserRelationOrderQty(user.getId()));
        resultMap.put("goodsQty", getUserRelationCodeGoodsQty(user.getId()));
        return resultMap;
    }

    @Resource
    private ZjStoreOutboundReceiptSendService storeOutboundReceiptSendService;

    // 删除用户
    @Override
    @Transactional
    public void deleteBatchByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return;
        }
        // 关联工单
        QueryWrapper<ZjWorkUser> workUserQueryWrapper = new QueryWrapper<>();
        workUserQueryWrapper.select("user_id");
        workUserQueryWrapper.in("user_id", ids);
        workUserQueryWrapper.last("group by user_id limit 10");
        List<ZjWorkUser> userList = workUserService.list(workUserQueryWrapper);
        exceptionMessage(userList.stream().map(ZjWorkUser::getUserId).toList(), "工单");
        // 编码
        QueryWrapper<ZjCodeUserRegister> codeUserRegisterQueryWrapper = new QueryWrapper<>();
        codeUserRegisterQueryWrapper.select("user_id");
        codeUserRegisterQueryWrapper.in("user_id", ids);
        codeUserRegisterQueryWrapper.last("group by user_id limit 10");
        List<ZjCodeUserRegister> userRegisterList = codeUserRegisterService.list(codeUserRegisterQueryWrapper);
        exceptionMessage(userRegisterList.stream().map(ZjCodeUserRegister::getUserId).toList(), "一物一码");
        // 查询关联的出库的收货客户
        List<Long> userIds = storeOutboundReceiptSendService.getUserIdByDelUserId(ids);
        exceptionMessage(userIds, "仓库出库收货客户");
        userContactService.deleteBatchByUserIds(ids);
        userService.removeByIds(ids);
    }

    private void exceptionMessage(List<Long> ids, String message) {
        if (CollectionUtil.isEmpty(ids)) {
            return;
        }
        QueryWrapper<ZjUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.select("name");
        userQueryWrapper.in("id", ids);
        List<ZjUser> users = userService.list(userQueryWrapper);
        Assert.isTrue(false, "用户[ " + users.stream().map(u -> {
            return u.getName() + " " + u.getPhone();
        }).collect(Collectors.joining("；")) + " ]已与" + message + "关联，不允许删除用户");
    }

    // 获取客户导出数据
    @Override
    public List<UserExcelExport> getUserExportExcel(Long custAccId, UserSelectVo selectVo) {
        List<UserListVo> voList = userService.getList(custAccId, selectVo);
        List<Long> userIds = voList.stream().map(UserListVo::getId).toList();
        List<ZjWorkUser> workUserList = workUserService.getByUserIds(userIds);
        List<ZjCodeUserRegister> userRegisterList = codeUserRegisterService.getByUserIds(userIds);
        return voList.stream().map(vo -> {
            UserExcelExport userExcelExport = new UserExcelExport();
            BeanUtil.copyProperties(vo, userExcelExport);
            userExcelExport.setOrderNo((int) workUserList.stream().filter(f -> Objects.equals(f.getUserId(), vo.getId())).count());
            userExcelExport.setProductNo((int) userRegisterList.stream().filter(f -> Objects.equals(f.getUserId(), vo.getId())).count());
            return userExcelExport;
        }).toList();
    }

    @Override
    public List<ZjUserContact> getUserContactByName(String name) {
        if (name != null && StringUtils.isNotBlank(name)) {
            QueryWrapper<ZjUserContact> wrapper = new QueryWrapper<>();
            wrapper.like("username", name);
            return userContactMapper.selectList(wrapper);
        } else {
            return new ArrayList<>();
        }
    }
}
